package com.ysjy.course.exception;

import com.mysql.cj.jdbc.exceptions.CommunicationsException;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.dto.ResultDTO;
import io.lettuce.core.RedisCommandTimeoutException;
import io.lettuce.core.RedisConnectionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.builder.IncompleteElementException;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.exceptions.JedisDataException;

import javax.management.ReflectionException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.sql.SQLNonTransientConnectionException;

/**
 * @author: lbh
 * @date: 2019-07-16 16:40
 * @description: 全局异常捕获类
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {


    /**
     * @description: MyException异常捕获集中处理方法1
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: handleMyException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = MyException.class)
    @ResponseBody
//    public ResultDTO handleMyException(HttpServletRequest request, Object handler, MyException e)  throws IOException {
    public ResultDTO handleMyException(HttpServletRequest request, Object handler, MyException e)  throws IOException {
        String url = request.getRequestURI();
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        log.error("【自定义的业务参数校验异常】：{}", e.getMessage());
//        return ResultVO.failure(e.getCode(), e.getMessage());
        return new ResultDTO(false,e.getCode().toString(), e.getMessage());
    }

    /**
     * @description: HttpRequestMethodNotSupportedException异常捕获集中处理方法2
     * @author: lbh
     * @date: 2019-07-16
     * @methodsName: handleHttpRequestMethodNotSupportedException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public ResultDTO handleHttpRequestMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException e)  throws IOException{
        String url = request.getRequestURI();
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:"+url);
        if(StringUtils.equals("GET",e.getMethod())){
            log.error("当前发起请求的方式为："+e.getMethod()+"，与接口要求的请求方式不一致！请使用POST请求方式！");
            return new ResultDTO(false,"10000001","当前发起请求的方式为："+e.getMethod()+"，与接口要求的请求方式不一致！请使用POST请求方式！");
        }else if(StringUtils.equals("POST",e.getMethod())){
            log.error("当前发起请求的方式为："+e.getMethod()+"，与接口要求的请求方式不一致！请使用GET请求方式！");
            return new ResultDTO(false,"10000002","当前发起请求的方式为："+e.getMethod()+"，与接口要求的请求方式不一致！请使用GET请求方式！");
        }else{
            log.error("当前发起请求的方式为："+e.getMethod()+"，与接口要求的请求方式不一致！请使用接口所要求的请求方式！");
            return new ResultDTO(false,"10000003","当前发起请求的方式为："+e.getMethod()+"，与接口要求的请求方式不一致！请使用接口所要求的请求方式！");
        }
    }

    /**
     * @description: MissingServletRequestParameterException异常捕获集中处理方法3
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: handleMissingServletRequestParameterException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    @ResponseBody
    public ResultDTO handleMissingServletRequestParameterException(HttpServletRequest request, Object handler, MissingServletRequestParameterException e)  throws IOException {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.error("当前发起的请求缺少接口参数："+((MissingServletRequestParameterException)e).getMessage()+",缺少的参数名称为："+((MissingServletRequestParameterException) e).getParameterName()+",缺少的参数类型为："+((MissingServletRequestParameterException) e).getParameterType());
        return new ResultDTO(false,"10000004","当前发起的请求缺少接口参数："+((MissingServletRequestParameterException)e).getMessage()+",缺少的参数名称为："+((MissingServletRequestParameterException) e).getParameterName()+",缺少的参数类型为："+((MissingServletRequestParameterException) e).getParameterType());
    }


    /**
     * @description: HttpMediaTypeNotSupportedException异常捕获集中处理方法4
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: handleHttpMediaTypeNotSupportedException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = HttpMediaTypeNotSupportedException.class)
    @ResponseBody
    public ResultDTO handleHttpMediaTypeNotSupportedException(HttpServletRequest request, Object handler, HttpMediaTypeNotSupportedException e)  throws IOException {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
           /*  ((HttpMediaTypeNotSupportedException) e)
           log.error("当前1发起请求【e.getContentType().getType()】方式的ContentType为："+e.getContentType().getType());//application
                log.error("当前2发起请求【e.getContentType().getSubtype()】方式的ContentType为："+e.getContentType().getSubtype());//x-www-form-urlencoded
                log.error("当前3发起请求【e.getContentType().getParameters()】方式的ContentType为："+e.getContentType().getParameters());//{charset=UTF-8}
                log.error("当前4发起请求【e.getContentType().toString()】方式的ContentType为："+e.getContentType().toString());//application/x-www-form-urlencoded;charset=UTF-8
                log.error("当前5发起请求【e.getMessage()】方式的ContentType为："+e.getMessage());//Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
                log.error("当前6发起请求【e.toString()】方式的ContentType为："+e.toString());//Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
                log.error("当前7发起请求【e.getLocalizedMessage()】方式的ContentType为："+e.getLocalizedMessage());//Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
*/
        if(e.getContentType().toString().contains("application/x-www-form-urlencoded")){
            log.error("当前发起请求方式的ContentType为："+e.getContentType().toString()+"，与接口要求的请求方式不一致！请使用application/json的ContentType方式！");
            return new ResultDTO(false,"10000005", "当前发起请求的方式为："+e.getContentType().toString()+"，与接口要求的请求方式不一致！请使用application/json的ContentType方式！");
        }
        log.error("当前发起请求方式的ContentType为："+e.getContentType().toString()+"，与接口要求的请求方式不一致！请使用application/x-www-form-urlencoded或者application/json的ContentType方式，同时接口参数上使用@RequestBody注解！");
        return new ResultDTO(false,"10000006",  "当前发起请求方式的ContentType为："+e.getContentType().toString()+"，与接口要求的请求方式不一致！请使用application/x-www-form-urlencoded或者application/json的ContentType方式，同时接口参数上使用@RequestBody注解！");
    }

    /**
     * @description: HttpMessageNotReadableException异常捕获集中处理方法5
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: handleHttpMessageNotReadableException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    @ResponseBody
    public ResultDTO handleHttpMessageNotReadableException(HttpServletRequest request, Object handler, HttpMessageNotReadableException e)  throws IOException {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        //((HttpMessageNotReadableException) e)
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        if(StringUtils.equals(e.toString(),"")){
            log.error("当前发起请求方式为："+e.getMessage()+"，与接口要求的不一致！");
            return new ResultDTO(false,"10000007", "当前发起请求的方式为："+e.getMessage()+"，与接口要求的不一致！");
        }
        log.error("当前发起请求方式的ContentType为："+e.getMessage()+"，与接口要求的不一致！");
        return new ResultDTO(false,"10000008","当前发起请求的方式为："+e.getMessage()+"，与接口要求的不一致！");
    }



    /**
     * @description: RedisCommandTimeoutException异常捕获集中处理方法6
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: RedisCommandTimeoutException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value =RedisCommandTimeoutException.class)
    //@ExceptionHandler(value = {RedisCommandTimeoutException.class, RedisConnectionException.class})
    @ResponseBody
    public ResultDTO handleRedisCommandTimeoutException(HttpServletRequest request, Object handler, RedisCommandTimeoutException e)  throws IOException {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        //((HttpMessageNotReadableException) e)
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("请求redis数据库时发生超时异常，请检查网络状态或查看redis服务是否已成功开启或者密码错误！");
        return new ResultDTO(false,"10000009", "请求redis数据库时发生超时异常，请检查网络状态或查看redis服务是否已成功开启或者密码错误！");
    }


    /**
     * @description: RedisConnectionException异常捕获集中处理方法7
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: RedisConnectionException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {RedisConnectionException.class})
    @ResponseBody
    public ResultDTO handleRedisConnectionException(HttpServletRequest request, Object handler, RedisConnectionException e)  throws IOException {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        //((HttpMessageNotReadableException) e)
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("连接redis数据库时发生超时异常，请检查网络状态或查看redis服务是否已成功开启或者密码错误！");
        return new ResultDTO(false,"10000010", "连接redis数据库时发生超时异常，请检查网络状态或查看redis服务是否已成功开启或者密码错误！");
    }


    /**
     * @description: CommunicationsException异常捕获集中处理方法8
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: CommunicationsException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {CommunicationsException.class})
    @ResponseBody
    public ResultDTO handleCommunicationsException(HttpServletRequest request, Object handler, CommunicationsException e)  throws IOException {
        String url = request.getRequestURI();
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        //((HttpMessageNotReadableException) e)
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("连接mysql数据库时发生超时异常，请检查网络状态或查看mysql服务是否已成功开启！");
        return new ResultDTO(false,"10000011", "连接mysql数据库时发生超时异常，请检查网络状态或查看mysql服务是否已成功开启！");
    }


    /**
     * @description: IOException异常捕获集中处理方法9
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: IOException
     * @throws: IOException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {IOException.class})
    @ResponseBody
    public ResultDTO handleIOException(HttpServletRequest request, Object handler, IOException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        //((HttpMessageNotReadableException) e)
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("本次请求发生了IO异常，具体的异常信息为："+e.getMessage());
        return new ResultDTO(false,"10000012", "本次请求发生了IO异常，具体的异常信息为："+e.getMessage());
    }

    /**
     * @description: OSSException异常捕获集中处理方法10
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: OSSException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    /*@ExceptionHandler(value = {OSSException.class})
    @ResponseBody
    public ResultDTO handleOSSException(HttpServletRequest request, Object handler, OSSException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        //((HttpMessageNotReadableException) e)
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("本次oss上传请求发生异常，具体的异常信息为："+e.getMessage()+"捕获一个OSSException，这意味着您的请求已发送到OSS，但由于某种原因以错误响应被拒绝。错误信息:"+e.getErrorMessage()+"；错误代码:"+e.getErrorCode()+"；请求ID:"+e.getRequestId()+"；主机ID:"+e.getHostId());
        return ResultVO.failure(413, "本次oss上传请求发生异常，具体的异常信息为："+e.getMessage()+"捕获一个OSSException，这意味着您的请求已发送到OSS，但由于某种原因以错误响应被拒绝。错误信息:"+e.getErrorMessage()+"；错误代码:"+e.getErrorCode()+"；请求ID:"+e.getRequestId()+"；主机ID:"+e.getHostId());
    }*/

    /**
     * @description: ClientException异常捕获集中处理方法11
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: ClientException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
   /* @ExceptionHandler(value = {ClientException.class})
    @ResponseBody
    public ResultDTO handleClientException(HttpServletRequest request, Object handler, ClientException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("本次oss上传请求发生异常，具体的异常信息为："+e.getMessage()+"捕获了一个ClientException，这意味着客户机在尝试与OSS通信时遇到了严重的内部问题，例如无法访问网络。错误信息:"+e.getErrorMessage()+"；错误代码:"+e.getErrorCode()+"；请求ID:"+e.getRequestId());
        return ResultVO.failure(413, "本次oss上传请求发生异常，具体的异常信息为："+e.getMessage()+"捕获了一个ClientException，这意味着客户机在尝试与OSS通信时遇到了严重的内部问题，例如无法访问网络。错误信息:"+e.getErrorMessage()+"；错误代码:"+e.getErrorCode()+"；请求ID:"+e.getRequestId());
    }*/


    //redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.
    /**
     * @description: JedisDataException异常捕获集中处理方法12
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: JedisDataException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {JedisDataException.class})
    @ResponseBody
    public ResultDTO handleJedisDataException(HttpServletRequest request, Object handler, JedisDataException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("连接redis数据库时发生超时异常，如果异常信息为："+e.getMessage()+" ===NOAUTH Authentication required.则说明无权访问redis，可能原因是密码错误！");
        return new ResultDTO(false,"10000015", "连接redis数据库时发生超时异常，如果异常信息为："+e.getMessage()+" ===NOAUTH Authentication required.则说明无权访问redis，可能原因是密码错误！");
    }

    /**
     * @description: NodeRegistryException异常捕获集中处理方法13
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: NodeRegistryException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    /*@ExceptionHandler(value = {NodeRegistryException.class})
    @ResponseBody
    public ResultDTO handleNodeRegistryException(HttpServletRequest request, Object handler, NodeRegistryException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("====分布式定时任务LTS在连接redis或者zookeeper注册中心时无法注册，异常信息为："+e.getMessage()+" ===可能原因是redis或者zookeeper的服务尚未开启或密码错误！");
        return ResultVO.failure(413, "====分布式定时任务LTS在连接redis或者zookeeper注册中心时无法注册，异常信息为："+e.getMessage()+" ===可能原因是redis或者zookeeper的服务尚未开启或密码错误！");
    }*/


    /**
     * @description: BindException异常捕获集中处理方法14
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: BindException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {BindException.class})
    @ResponseBody
    public ResultDTO handleBindException(HttpServletRequest request, Object handler, BindException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("====接口请求参数映射时，发生BindException异常，异常信息为："+e.getMessage()+" ===可能原因是参数类型无法匹配！");
        return new ResultDTO(false,"10000016", "====接口请求参数映射时，发生BindException异常，异常信息为："+e.getMessage()+" ===可能原因是参数类型无法匹配！");
    }


    /**
     * @description: NumberFormatException异常捕获集中处理方法15
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: NumberFormatException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {NumberFormatException.class})
    @ResponseBody
    public ResultDTO handleNumberFormatException(HttpServletRequest request, Object handler, NumberFormatException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("====接口请求参数映射时，发生NumberFormatException异常，异常信息为："+e.getMessage()+" ===原因是所传参数值类型无法正确匹配数字类型的参数！");
        return new ResultDTO(false,"10000017", "====接口请求参数映射时，发生NumberFormatException异常，异常信息为："+e.getMessage()+" ===原因是所传参数值类型无法正确匹配数字类型的参数！");
    }


    /**
     * @description: SQLIntegrityConstraintViolationException异常捕获集中处理方法16
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: SQLIntegrityConstraintViolationException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {SQLIntegrityConstraintViolationException.class})
    @ResponseBody
    public ResultDTO handleSQLIntegrityConstraintViolationException(HttpServletRequest request, Object handler, SQLIntegrityConstraintViolationException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("====接口请求入库时，发生SQLIntegrityConstraintViolationException异常，异常信息为："+e.getMessage()+" ===原因是所传参数值在数据库被标识为：UNIQUE KEY或者是NOT NULL，是唯一不能重复的！");
        return new ResultDTO(false,"10000018", "====接口请求入库时，发生SQLIntegrityConstraintViolationException异常，异常信息为："+e.getMessage()+" ===原因是所传参数值在数据库被标识为：UNIQUE KEY或者是NOT NULL，是唯一不能重复的！");
    }


    /**
     * @description: ReflectionException---MyBatisSystemException异常捕获集中处理方法17
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: ReflectionException---MyBatisSystemException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
//    @ExceptionHandler(value = {ReflectionException.class, MyBatisSystemException.class})
    @ExceptionHandler(value = {ReflectionException.class})
    @ResponseBody
//    public ResultDTO handleMyBatisSystemException(HttpServletRequest request, Object handler, MyBatisSystemException e1,ReflectionException e2)   {
    public ResultDTO handleMyBatisSystemException(HttpServletRequest request, Object handler, ReflectionException e2)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
//        log.info("=e1.getLocalizedMessage()==:"+e1.getLocalizedMessage());
//        log.info("=e1.getMessage()==:"+e1.getMessage());
//        log.info("=e1.toString()==:"+e1.toString());

        log.info("=e2.getLocalizedMessage()==:"+e2.getLocalizedMessage());
        log.info("=e2.getMessage()==:"+e2.getMessage());
        log.info("=e2.toString()==:"+e2.toString());

//        log.error("====接口请求时，发生MyBatisSystemException异常，异常信息为："+e1.getMessage()+" ===原因可能是mapper.xml里面#号取值时的字段错误或者<test>里面的字段错误！");
        log.error("====接口请求时，发生ReflectionException异常，异常信息为："+e2.getMessage()+" ===原因可能是mapper.xml里面#号取值时的字段错误或者<test>里面的字段错误！");
        return new ResultDTO(false,"10000019", "====接口请求时，发生MyBatisSystemException/ReflectionException异常，异常信息为："+e2.getMessage()+" ===原因可能是mapper.xml里面#号取值时的字段错误或者<test>里面的字段错误！");
    }

    /**
     * @description: IncompleteElementException异常捕获集中处理方法18
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: IncompleteElementException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {IncompleteElementException.class})
    @ResponseBody
    public ResultDTO handleIncompleteElementException(HttpServletRequest request, Object handler, IncompleteElementException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("====接口请求查询时，发生IncompleteElementException异常，异常信息为："+e.getMessage()+" ===原因是查询数据库时，mapper.xml里面的resultType误写成了resultMap或者是resultMap尚未定义！");
        return new ResultDTO(false,"10000020","====接口请求查询时，发生IncompleteElementException异常，异常信息为："+e.getMessage()+" ===原因是查询数据库时，mapper.xml里面的resultType误写成了resultMap或者是resultMap尚未定义！");
    }

    /**
     * @description: TooManyResultsException异常捕获集中处理方法19
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: TooManyResultsException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {TooManyResultsException.class})
    @ResponseBody
    public ResultDTO handleTooManyResultsException(HttpServletRequest request, Object handler, TooManyResultsException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("====接口请求查询时，发生IncompleteElementException异常，异常信息为："+e.getMessage()+" ===原因是查询期望结果集是一条记录，结果是多条记录！");
        return new ResultDTO(false,"10000021", "====接口请求查询时，发生IncompleteElementException异常，异常信息为："+e.getMessage()+" ===原因是查询期望结果集是一条记录，结果是多条记录！");
    }


    /**
     * @description: SQLNonTransientConnectionException异常捕获集中处理方法20
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: SQLNonTransientConnectionException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {SQLNonTransientConnectionException.class})
    @ResponseBody
    public ResultDTO handleSQLNonTransientConnectionException(HttpServletRequest request, Object handler, SQLNonTransientConnectionException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());
        log.error("====接口请求查询时，发生SQLNonTransientConnectionException异常，异常信息为："+e.getMessage()+" ===原因可能是数据库服务提供的是仅内网可访问的ip地址，无法访问导致的！");
        return new ResultDTO(false,"10000022",  "====接口请求查询时，发生SQLNonTransientConnectionException异常，异常信息为："+e.getMessage()+" ===原因可能是数据库服务提供的是仅内网可访问的ip地址，无法访问导致的！");
    }



   /* else {
        log.error("【接口地址异常】：", e);
         return ResultVO.failure(-1, "请求的接口根路径错误！");

//            response.setContentType("application/json");
//            response.setCharacterEncoding("utf-8");
//            response.getWriter().print("".toString());

        //这里调用父类的异常处理方法，实现其他不需要的异常交给SpringMVC处理
            *//*ModelAndView modelAndView=super.doResolveException(request, response, handler, e);
            return modelAndView;*//*
    }
*/


    /**
     * @description: MethodArgumentNotValidException 异常捕获集中处理方法22   使用@Validated注解结合@NotNull(message="是必传参数，不能为空")注解来判断对象参数里面的属性非空
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: MethodArgumentNotValidException
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    @ResponseBody
    public ResultDTO handleMethodArgumentNotValidException(HttpServletRequest request, Object handler, MethodArgumentNotValidException e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());//示例值为：
        /*// Validation failed for argument [0]
        in public com.github.maxcompute.web.support.Result<com.alibaba.fastjson.JSONObject> com.github.maxcompute.web.controller.pharos.TableController.
                noVisitTabStatis(com.github.maxcompute.biz.portal.model.TableQueryParam): [Field error in object 'tableQueryParam' on field 'type': rejected value [null];
        codes [NotNull.tableQueryParam.type,NotNull.type,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable:
        codes [tableQueryParam.type,type]; arguments []; default message [type]]; default message [type字段--表类型：hive,phoenix,view,tidb 不能为空]]*/
        String error=e.getMessage();
        String message=error.substring(error.lastIndexOf("[")+1).replaceAll("]]","");

        String aa=error.substring(error.indexOf("]; default message [")+1).replaceAll("default message","");
        String filed= aa.substring(1,aa.indexOf("]")).replaceAll(";","").trim().substring(1);
        String totalAlertMessage=filed+message;
        log.info("==========totalAlertMessage=================："+totalAlertMessage);

        log.error("====发生MethodArgumentNotValidException异常，异常信息为："+e.getMessage()+" ===原因是："+totalAlertMessage);
       return new ResultDTO(false,"10000023", "====发生MethodArgumentNotValidException异常，=原因是："+totalAlertMessage);
    }


    /**
     * @description: Exception 异常捕获集中处理方法23
     * @author: lbh
     * @date:  2019-07-16
     * @methodsName: Exception
     * @version:V1.0
     * @param
     * @return Map<String,Object>
     */
    @ExceptionHandler(value = {Exception.class})
    @ResponseBody
    public ResultDTO handleException(HttpServletRequest request, Object handler, Exception e)   {
        String url = request.getRequestURI();
        log.info("=====产生异常的接口地址url----request.getRequestURI()=======:" + url);
        //api返回异常拦截【自定义异常要想进来的话，这里需要根据项目根路径自定义接口前缀】
        log.info("=e.getLocalizedMessage()==:"+e.getLocalizedMessage());
        log.info("=e.getMessage()==:"+e.getMessage());
        log.info("=e.toString()==:"+e.toString());//示例值为：

        log.error("====发生Exception异常，异常信息为："+e.getMessage());
//        return new ResultDTO(false,"10000024", "====发生Exception异常");
//        return new ResultDTO<>(false,ErrorCode.SYSTEM_EXCEPTION.getCode(),ErrorCode.SYSTEM_EXCEPTION.getMessage());
        return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
    }

    public static void main(String[] args) {

        String error="Validation failed for argument [0]\n" +
                "        in public com.github.maxcompute.web.support.Result<com.alibaba.fastjson.JSONObject> com.github.maxcompute.web.controller.pharos.TableController.\n" +
                "                noVisitTabStatis(com.github.maxcompute.biz.portal.model.TableQueryParam): [Field error in object 'tableQueryParam' on field 'type': rejected value [null];\n" +
                "        codes [NotNull.tableQueryParam.type,NotNull.type,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable:\n" +
                "        codes [tableQueryParam.type,type]; arguments []; default message [type]]; default message [type字段--表类型：hive,phoenix,view,tidb 不能为空]]";

//        String error="Validation failed for argument [0] in public com.github.maxcompute.web.support.Result<com.alibaba.fastjson.JSONObject> com.github.maxcompute.web.controller.pharos.TableController.noVisitTabStatis(com.github.maxcompute.biz.portal.model.TableQueryParam): [Field error in object 'tableQueryParam' on field 'owner': rejected value [null]; codes [NotNull.tableQueryParam.owner,NotNull.owner,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [tableQueryParam.owner,owner]; arguments []; default message [owner]]; default message [不能为空]]  \n";

        log.info("==========error========message=========："+error.substring(error.lastIndexOf("[")+1).replaceAll("]]",""));

        log.info("==========error========filed=====11====："+error.substring(error.indexOf("]; default message [")+1));
        log.info("==========error========filed=========："+error.substring(error.indexOf("]; default message [")+1).replaceAll("default message",""));
        String aa=error.substring(error.indexOf("]; default message [")+1).replaceAll("default message","");
        log.info("==========error========aa=========："+aa);

        log.info("==========error========filed=====1112====："+ aa.substring(1,aa.indexOf("]")).replaceAll(";","").trim().substring(1));
    }



}
